

/*Base*/

function Class() { }
Class.prototype.construct = function() {};
Class.extend = function(def) {
	var classDef = function() {
		if (arguments[0] !== Class) { this.construct.apply(this, arguments); }
	};

	var proto = new this(Class);
	var superClass = this.prototype;

	for (var n in def) {
		var item = def[n];                      
		if (item instanceof Function) item.$ = superClass;
		proto[n] = item;
	}

	classDef.prototype = proto;
	classDef.extend = this.extend;      
	return classDef;
};

var Component = Class.extend({
	target: null,
	init: function(){
		this.target = this.buildElement();
	},
	buildOn: function(element){
		element.append(this.target);
	},
	addClass: function(classname){
		this.target.addClass(classname);
	},
	removeClass: function(classname){
		this.target.removeClass(classname);
	},
	buildElement: function(){}
});

/*Extentions*/
Array.prototype.each=function(block){
	for(var i=0; i<this.length; i++){
		block(this[i]);
	}
}
Array.prototype.collect=function(block){
	var arr = new Array();
	for(var i=0; i<this.length; i++){
		arr[arr.length] = block(this[i]);
	}
	return arr;
}
Array.prototype.find=function(block){
	for(var i=0; i<this.length; i++){
		if(block(this[i])) return this[i];
	}
	return null;
}
if (typeof String.prototype.startsWith != 'function') {
	String.prototype.startsWith = function (str){
		return this.indexOf(str) == 0;
	};
}
/*Containers*/
var IContainer = Component.extend({
	elements: null,
	init: function(){
		arguments.callee.$.init.call(this);
		this.clear();
	},
	add: function(element){
		var elements = this.elements;
		elements[elements.length] = element;
		return this;
	},
	clear: function(){
		this.elements = new Array();
	},
	buildOn: function(element){
		var _target = this.target;
		element.append(_target);
		this.elements.each(function(e){
			e.buildOn(_target);
		});
	}
});

var Container = IContainer.extend({
	construct: function(classname){
		this.init();
		this.addClass(classname);
	},
	add: function(element){
		var elements = this.elements;
		elements[elements.length] = element;
		return this;
	},
	buildElement:function (){
		return $("<div></div>");
	}
});

/* Menus*/
var ContainerGroup = Container.extend({
	construct: function(classname){
		this.init();
		this.addClass(classname);
	},
	add: function(element){
		var elements = this.elements;
		elements[elements.length] = element;
		element.parent = this;
		return this;
	}
});

var Menu = IContainer.extend({
	text:"",
	action:null,
	pane: null,
	construct:function(name, action, pane){
		this.text = name;
		this.action = action;
		this.pane = pane;
		this.init();
		this.addClass("op-menu");
		var a = this.a();
		a.eparent = this;
		a.active = this.active;
	},
	buildElement: function(){
		return $("<a></a>").append(this.text).click(this.action);
	},
	active: function(){
		if(this.eparent){
			this.eparent.active();
			return;
		}
		if(this.parent){
			this.parent.elements.each(function(e){
				e.removeClass("op-menu-selected");
			});
		}
		this.addClass("op-menu-selected");
		this.buildMenuItems();
	},
	a: function(){
		return this.target[0];
	},
	buildMenuItems:function(){
		var arr = this.elements;
		if(arr.length == 0) return;
		var ptar = this.pane.target;
		ptar.empty();
		
		ptar.append($("<span></span").append(this.text));
		var that = this;
		arr.each(function(e){
			e.buildOn(ptar);
			e.parent = that;
		});
		if(arr[arr.length-1].firstResponse)
			arr[arr.length-1].active();
	},
	buildOn: function(element){
		var _target = this.target;
		element.append(_target);
	}
});

var MenuItem = Component.extend({
	text: null,
	action: null,
	firstResponse: null,
	construct: function(text, action, firstResponse){
		this.text = text;
		this.action = action;
		this.firstResponse = firstResponse;
		this.init();
		var a = this.target[0];
		a.eparent = this;
		a.active = this.active;
	},
	active: function(){
		if(this.eparent){
			this.eparent.active();
			return;
		}
		this.parent.elements.each(function(e){
			e.removeClass("op-menu-selected");
		});
		this.addClass("op-menu-selected");
	},
	buildElement: function(){
		return $("<a></a>").append(this.text);
	},
	buildOn: function(element){
		var _target = this.target;
		element.append(_target.click(this.action));
	}
});
/*Actions*/

/*Components*/
var Img = Component.extend({
	src:null,
	construct:function(src){
		this.src = src;
		this.init();
	},
	buildElement: function(){
		return $("<img></img>").attr("src",this.src);
	},
	size: function(x, y){
		var target = this.target;
		target.attr("width",x);
		target.attr("height",y);
	}
});

var Anchor = Component.extend({
	text: null,
	href: null,
	construct: function(text, href){
		this.text = text,
		this.href = href;
		this.init();
		this.addClass("op-a");
	},
	a:function(){
		return this.target[0];
	},
	buildElement: function(){
		return $("<a></a>").attr("href",this.href).append(this.text);
	},
	tar: function(t){
		this.target.attr('target',t);
		return this;
	},
	title: function(t) {
		this.target.attr('title',t);
		return this;
	}
});

var HTML = Component.extend({
	html: null,
	tag: null,
	construct: function(html, tag){
		this.html = html;
		this.tag = tag;
		if(!tag) this.tag = "<div></div>";
		this.init();
		this.addClass("op-html");
	},
	buildElement: function(){
		return $(this.tag).append(this.html);
	}
});







